home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / ab20_archive / languages / assembly / powervisor_113.lzh / s / pv / assem.pv next >
Text File  |  1991-10-31  |  32KB  |  1,434 lines

  1. /*=======================================================*/
  2. /*                                                                            */
  3. /* Simple assembler for PowerVisor        V1.0                    */
  4. /*                                                                            */
  5. /* © Jorrit Tyberghein  18 Sep 1991    V1.0                        */
  6. /*                                31 Oct 1991 V1.1                        */
  7. /*                                                                            */
  8. /*=======================================================*/
  9.  
  10. /* Usage : execute this script after setting the start address in the 'rc'
  11.               variable (use 'rx' to call this script)
  12.               Press enter to stop the assembler
  13.  
  14.     This assembler assembles the following commands :
  15.  
  16.         move (with movea)
  17.         moveq
  18.         movem
  19.         tst
  20.         add
  21.         sub
  22.         or
  23.         eor
  24.         and
  25.         addi
  26.         subi
  27.         eori
  28.         ori
  29.         andi
  30.         addq
  31.         subq
  32.         not
  33.         nop
  34.         neg
  35.         swap
  36.         illegal
  37.         reset
  38.         rts
  39.         bra
  40.         bsr
  41.         jmp
  42.         jsr
  43.         b<condition>
  44.         negx
  45.         clr
  46.         cmp
  47.         cmpi
  48.         cmpa
  49.         cmpm
  50.         db<condition>
  51.         dbra
  52.         lea
  53.         pea
  54.         dc (only .W and .L)
  55.  
  56.  
  57.     Almost all 68030 addressing modes are supported. Note that you can
  58.     use PowerVisor expressions almost everywhere where a number is
  59.     expected. But don't make these expressions to complex or the parser
  60.     in this assembler will get confused.
  61.                 xxx    number
  62.                 d16    16 bit displacement
  63.                 d8        8 bit displacement
  64.                 bd        base displacement
  65.                 od        outer displacement
  66.                 An        address register
  67.                 Dn        data register
  68.                 Xn        data or address register
  69.                 PC        program counter
  70.  
  71.                 Note that you can append a size specifier (.W or .L) to Xn
  72.                 and a scale factor (*1 2 4 8)
  73.  
  74.         #<data>
  75.         (xxx).W
  76.         (xxx).L
  77.         (d16,PC)
  78.         (d8,PC,Xn)
  79.         (bd,PC,Xn)
  80.         ([bd,PC,Xn],od)
  81.         ([bd,PC],Xn,od)
  82.         (d16,An)
  83.         (d8,An,Xn)
  84.         (bd,An,Xn)
  85.         ([bd,An,Xn],od)
  86.         ([bd,An],Xn,od)
  87.         (An)+
  88.         -(An)
  89.         (An)
  90.         An
  91.         Dn
  92.  
  93.  
  94.     Instead of a machinelanguage command you can also use dot commands. Start
  95.     the following commands with a dot :
  96.  
  97.         b            goto previous instruction
  98.         pc            set new program counter
  99.         q            quit assembler (same as empty line)
  100.         h            for dot command help
  101.         to            toggle old mode
  102.         tc            toggle commandline mode
  103.         c            copy current instruction to cmdline
  104.         s            skip the current instruction (only in old or cmd mode)
  105.         cc            copy current instruction to buffer
  106.         gc            copy buffer to cmdline
  107.  
  108.  
  109.     Warning ! This assembler also assembles instructions even if there is
  110.     no meaningfull interpretation. For example, you can assemble :
  111.  
  112.         move.l #1,#2
  113.  
  114.  
  115.     Warning ! When the assembler is stopped because of an internal error
  116.     (this can occur when your expressions are too complex), it looks as
  117.     if PowerVisor hangs. Type the following command on the CLI to get
  118.     PowerVisor back in control :
  119.  
  120.         rx "address rexx_powervisor async"
  121.  
  122. */
  123.  
  124.  
  125. options results
  126.  
  127. /* The following assignments are the default modes. You can change the defaults */
  128. /* if you want */
  129. oldmode=1    /* Old mode, when true we display old instruction on screen */
  130. cmdmode=0    /* Cmd mode, when true we copy old instruction to string gadget */
  131.  
  132. 'sync'        /* Disable the PowerVisor commandline. We take control */
  133. 'void rc'    /* 'rc' contains address to start assembling, copy to ARexx variable */
  134. pc=result    /* 'pc' always contains the current program counter */
  135. oldpc=0        /* The previous program counter (used by the .B command) */
  136.  
  137. tmpcmd=0        /* Used by the .C command to temporary set cmdmode to true */
  138. buffer=''    /* Empty buffer */
  139.  
  140. 'void getcol(getlwin())'
  141. col=result    /* Number of columns on PowerVisor default logical window */
  142.  
  143.  
  144. /*-----------*/
  145. /* Main loop */
  146. /*-----------*/
  147.  
  148. do forever
  149.     'print "\('pc',%08lx) : "'        /* Print current address (program counter) */
  150.     'getx'                                /* Get coordinates on screen after address */
  151.     x=result
  152.     'gety'
  153.     y=result
  154.  
  155.     /*** If oldmode or cmdmode =1 we need the disassembly of the old instruction ***/
  156.     if (oldmode=1) | (cmdmode=1) | (tmpcmd>=1) then
  157.         do
  158.             'assign _mem=alloc(n,120)'
  159.             'pvcall 64 _mem' pc '0'    /* Disassemble */
  160.             isize=result                /* Result is size of old instruction */
  161.             'string _mem'                /* Copy string to ARexx */
  162.             oldasmstr=result
  163.             'free _mem'
  164.         end
  165.  
  166.     if oldmode=1 then                    /* We must show the old instruction */
  167.         do
  168.             'locate' x y
  169.             'print "'oldasmstr
  170.         end
  171.  
  172.     if tmpcmd=2 then 'void {pv 10 "'buffer'";scan *"INST"}'
  173.     else if (cmdmode=1) | (tmpcmd=1) then 'void {pv 10 "'oldasmstr'";scan *"INST"}'
  174.     else 'void {scan *"INST"}'
  175.     tmpcmd=0
  176.  
  177.     'string input'                        /* Get new instruction string (or dot command) */
  178.     asmstr=result
  179.  
  180.     'locate' x y                        /* Clear line after program counter */
  181.     'print "'copies(' ',col-x-1)'"'
  182.     'locate' x y                        /* Print instruction or dot command */
  183.     'print "'asmstr
  184.  
  185.     /*** First check if it is a dot command ***/
  186.     if substr(asmstr,1,1)='.' then
  187.         do
  188.             parse upper var asmstr '.' dotcmd args
  189.             if dotcmd='Q' then
  190.                 do
  191.                     'print \0a'
  192.                     'async'
  193.                     exit
  194.                 end
  195.             else if dotcmd='PC' then
  196.                 do
  197.                     'void' args
  198.                     if rc~=0 then 'print "\0aBad expression for programcounter !"'
  199.                     else
  200.                         do
  201.                             if (result=0) | (result%1=1) then
  202.                                 'print "\0aBad expression for programcounter !"'
  203.                             else pc=result
  204.                         end
  205.                 end
  206.             else if dotcmd='B' then
  207.                 do
  208.                     if oldpc=0 then
  209.                         'print "\0aNo previous program counter !"'
  210.                     else
  211.                         do
  212.                             pc=oldpc
  213.                             oldpc=0
  214.                         end
  215.                 end
  216.             else if dotcmd='GC' then tmpcmd=2
  217.             else if dotcmd='CC' then
  218.                 do
  219.                     'assign _mem=alloc(n,120)'
  220.                     'pvcall 64 _mem' pc '0'    /* Disassemble */
  221.                     isize=result                /* Result is size of old instruction */
  222.                     'string _mem'                /* Copy string to ARexx */
  223.                     buffer=result
  224.                     'free _mem'
  225.                 end
  226.             else if dotcmd='TO' then oldmode=1-oldmode
  227.             else if dotcmd='TC' then cmdmode=1-cmdmode
  228.             else if dotcmd='C' then tmpcmd=1
  229.             else if dotcmd='S' then
  230.                 do
  231.                     if (oldmode=1) | (cmdmode=1) then
  232.                         do
  233.                             pc=pc+isize
  234.                             'locate' x y
  235.                             'print "'oldasmstr
  236.                         end
  237.                     else 'print "\0aOnly use .s in <old mode> or <cmd mode> !"'
  238.                 end
  239.             else if dotcmd='H' then
  240.                 do
  241.                     'print "\0aMini Assembler V1.1\0a\0a"'
  242.                     'print ".b    goto previous instruction (only once)\0a"'
  243.                     'print ".pc   set new program counter\0a"'
  244.                     'print ".to   toggle <old mode> (ON/off)\0a"'
  245.                     'print ".tc   toggle <cmdline mode> (on/OFF)\0a"'
  246.                     'print ".c    copy current instruction to commandline\0a"'
  247.                     'print ".s    skip this instruction (in old or cmd mode)\0a"'
  248.                     'print ".cc   copy current instruction to buffer\0a"'
  249.                     'print ".gc   copy buffer to commandline\0a"'
  250.                     'print ".q    quit assembler (same as empty line)\0a"'
  251.                     'print ".h    this help\0a"'
  252.                 end
  253.             else 'print "\0aUnknown dot command (type .H for help) !"'
  254.             'print \0a'
  255.         end
  256.     /*** Else it could be an empty string (equivalent to .Q) ***/
  257.     else if asmstr='' then
  258.         do
  259.             'print \0a'
  260.             'async'
  261.             exit
  262.         end
  263.     /*** Else it should be a valid instruction ***/
  264.     else
  265.         do
  266.             'print \0a'
  267.             oldpc=pc
  268.             a=Assemble(asmstr)
  269.         end
  270. end
  271.  
  272.  
  273.  
  274. /*-----------------------------*/
  275. /* Assemble a string to memory */
  276. /*                                         */
  277. /* Input   : string                 */
  278. /* Uses    : pc                     */
  279. /* Changes : pc                     */
  280. /* Returns : 0 if error or 1     */
  281. /*-----------------------------*/
  282.  
  283. Assemble: procedure expose pc
  284. parse upper arg asmstr
  285.  
  286. parse var asmstr cmd arg
  287. cmd=strip(cmd)
  288. arg=strip(arg)
  289.  
  290. parse var cmd opcode '.' size
  291.  
  292. extra=0
  293.  
  294. if opcode='MOVE' then
  295.     do
  296.         call SplitArgs arg
  297.  
  298.         if source='CCR' then
  299.             do
  300.                 mdest=ModeBits(dest)
  301.                 if mdest=-1 then return 0
  302.                 code=x2d('42c0')
  303.                 arb=ArgRegBits(mdest'|'dest)
  304.                 if arb=-1 then return 0
  305.                 code=code+mdest*8+arb
  306.                 call PushWord code
  307.                 extwrd=extra
  308.                 if GetArg(mdest'|'dest'|W')=-1 then return 0
  309.             end
  310.         else if dest='CCR' then
  311.             do
  312.                 msource=ModeBits(source)
  313.                 if msource=-1 then return 0
  314.                 code=x2d('44c0')
  315.                 arb=ArgRegBits(msource'|'source)
  316.                 if arb=-1 then return 0
  317.                 code=code+msource*8+arb
  318.                 call PushWord code
  319.                 extwrd=extra
  320.                 if GetArg(msource'|'source'|W')=-1 then return 0
  321.             end
  322.         else if source='SR' then
  323.             do
  324.                 mdest=ModeBits(dest)
  325.                 if mdest=-1 then return 0
  326.                 code=x2d('40c0')
  327.                 arb=ArgRegBits(mdest'|'dest)
  328.                 if arb=-1 then return 0
  329.                 code=code+mdest*8+arb
  330.                 call PushWord code
  331.                 extwrd=extra
  332.                 if GetArg(mdest'|'dest'|W')=-1 then return 0
  333.             end
  334.         else if dest='SR' then
  335.             do
  336.                 msource=ModeBits(source)
  337.                 if msource=-1 then return 0
  338.                 code=x2d('46c0')
  339.                 arb=ArgRegBits(msource'|'source)
  340.                 if arb=-1 then return 0
  341.                 code=code+msource*8+arb
  342.                 call PushWord code
  343.                 extwrd=extra
  344.                 if GetArg(msource'|'source'|W')=-1 then return 0
  345.             end
  346.         else if source='USP' then
  347.             do
  348.                 if substr(dest,1,1)~='A' then
  349.                     do
  350.                         'print "Only address register allowed !\0a"'
  351.                         return 0
  352.                     end
  353.                 rb=RegBits(dest)
  354.                 if rb=-1 then return 0
  355.                 code=x2d('4e68')+rb
  356.                 call PushWord code
  357.             end
  358.         else if dest='USP' then
  359.             do
  360.                 if substr(source,1,1)~='A' then
  361.                     do
  362.                         'print "Only address register allowed !\0a"'
  363.                         return 0
  364.                     end
  365.                 rb=RegBits(source)
  366.                 if rb=-1 then return 0
  367.                 code=x2d('4e60')+rb
  368.                 call PushWord code
  369.             end
  370.         else
  371.             do
  372.                 mdest=ModeBits(dest)
  373.                 if mdest=-1 then return 0
  374.                 msource=ModeBits(source)
  375.                 if msource=-1 then return 0
  376.                 msb=MoveSizeBits(size)
  377.                 if msb=-1 then return 0
  378.                 code=msb*4096+mdest*64+msource*8
  379.                 arb=ArgRegBits(mdest'|'dest)
  380.                 if arb=-1 then return 0
  381.                 code=code+arb*512
  382.                 arb=ArgRegBits(msource'|'source)
  383.                 if arb=-1 then return 0
  384.                 code=code+arb
  385.                 call PushWord code
  386.                 extwrd=extra
  387.                 if GetArg(msource'|'source'|'size)=-1 then return 0
  388.                 extwrd=extwrd+extwrd-extra
  389.                 if GetArg(mdest'|'dest'|'size)=-1 then return 0
  390.             end
  391.     end
  392. else if (substr(opcode,1,1)='B') & (length(opcode)=3) then
  393.     do
  394.         'void' arg
  395.         if rc~=0 then
  396.             do
  397.                 'print "Bad integer !\0a"'
  398.                 return 0
  399.             end
  400.         arg=result
  401.         arg=arg-pc-2
  402.  
  403.         if opcode='BRA' then code=x2d('6000')
  404.         else if opcode='BSR' then code=x2d('6100')
  405.         else
  406.             do
  407.                 p=pos(substr(opcode,2,2),'HI LS CC CS NE EQ VC VS PL MI GE LT GT LE')
  408.                 if p=0 then
  409.                     do
  410.                         'print "Unknown opcode !\0a"'
  411.                         return 0
  412.                     end
  413.                 else code=x2d('6000')+((p-1)/3+2)*256
  414.             end
  415.  
  416.         if (size='B') | (size='S') then call PushWord code+MakeByte(arg)
  417.         else if (size='W') | (size='') then
  418.             do
  419.                 call PushWord code
  420.                 call PushWord arg
  421.             end
  422.         else if size='L' then
  423.             do
  424.                 call PushWord code+255
  425.                 call PushLong arg
  426.             end
  427.     end
  428. else if opcode='RTS' then call PushWord x2d('4e75')
  429. else if opcode='NOP' then call PushWord x2d('4e71')
  430. else if (opcode='TST') | (opcode='CLR') | (opcode='NEG') | (opcode='NEGX') | (opcode='NOT') then
  431.     do
  432.         msource=ModeBits(arg)
  433.         if msource=-1 then return 0
  434.         sb=SizeBits(size)
  435.         if sb=-1 then return 0
  436.         sb=sb*64
  437.         if opcode='TST' then code=x2d('4a00')+sb
  438.         else if opcode='NEG' then code=x2d('4400')+sb
  439.         else if opcode='NEGX' then code=x2d('4000')+sb
  440.         else if opcode='NOT' then code=x2d('4600')+sb
  441.         else code=x2d('4200')+sb
  442.         arb=ArgRegBits(msource'|'arg)
  443.         if arb=-1 then return 0
  444.         code=code+msource*8+arb
  445.         call PushWord code
  446.         extwrd=extra
  447.         if GetArg(msource'|'arg'|'size)=-1 then return 0
  448.     end
  449. else if (opcode='ADD') | (opcode='SUB') | (opcode='AND') | (opcode='OR') then
  450.     do
  451.         call SplitArgs arg
  452.         if opcode='ADD' then firstnib=x2d('d000')
  453.         else if opcode='SUB' then firstnib=x2d('9000')
  454.         else if opcode='OR' then firstnib=x2d('8000')
  455.         else firstnib=x2d('c000')
  456.  
  457.         if substr(dest,1,1)='D' then
  458.             do
  459.                 sb=SizeBits(size)
  460.                 if sb=-1 then return 0
  461.                 rb=RegBits(dest)
  462.                 if rb=-1 then return 0
  463.                 code=firstnib+rb*512+sb*64
  464.                 dest=source
  465.             end
  466.         else if substr(source,1,1)='D' then
  467.             do
  468.                 sb=SizeBits(size)
  469.                 if sb=-1 then return 0
  470.                 rb=RegBits(source)
  471.                 if rb=-1 then return 0
  472.                 code=firstnib+x2d('0100')+rb*512+sb*64
  473.             end
  474.         else
  475.             do
  476.                 'print "Must have at least one data register !\0a"'
  477.                 return 0
  478.             end
  479.         mdest=ModeBits(dest)
  480.         if mdest=-1 then return 0
  481.         arb=ArgRegBits(mdest'|'dest)
  482.         if arb=-1 then return 0
  483.         code=code+mdest*8+arb
  484.         call PushWord code
  485.         extwrd=extra
  486.         if GetArg(mdest'|'dest'|'size)=-1 then return 0
  487.     end
  488. else if (opcode='ADDA') | (opcode='SUBA') then
  489.     do
  490.         call SplitArgs arg
  491.         if substr(dest,1,1)='A' then
  492.             do
  493.                 s=AddressSizeBits(size)
  494.                 if s=-1 then return 0
  495.                 if opcode='ADD' then firstnib=x2d('d000')
  496.                 else firstnib=x2d('9000')
  497.                 rb=RegBits(dest)
  498.                 if rb=-1 then return 0
  499.                 code=firstnib+rb*512+s*64
  500.                 msource=ModeBits(source)
  501.                 if msource=-1 then return 0
  502.                 arb=ArgRegBits(msource'|'source)
  503.                 if arb=-1 then return 0
  504.                 code=code+msource*8+arb
  505.                 call PushWord code
  506.                 extwrd=extra
  507.                 if GetArg(msource'|'source'|'size)=-1 then return 0
  508.             end
  509.         else
  510.             do
  511.                 'print "ADDA must have a destination address register !\0a"'
  512.                 return 0
  513.             end
  514.     end
  515. else if (opcode='ADDI') | (opcode='SUBI') | (opcode='ADDQ') | (opcode='SUBQ') | (opcode='ANDI') | (opcode='CMPI') | (opcode='EORI') | (opcode='ORI') then
  516.     do
  517.         call SplitArgs arg
  518.         if substr(source,1,1)~='#' then
  519.             do
  520.                 'print "Bad immediate value !\0a"'
  521.                 return 0
  522.             end
  523.  
  524.         parse var source '#' imm
  525.         'void' imm
  526.         if rc~=0 then
  527.             do
  528.                 'print "Bad integer !\0a"'
  529.                 return 0
  530.             end
  531.         imm=result
  532.  
  533.         mdest=ModeBits(dest)
  534.         if mdest=-1 then return 0
  535.         sb=SizeBits(size)
  536.         if sb=-1 then return 0
  537.         arb=ArgRegBits(mdest'|'dest)
  538.         if arb=-1 then return 0
  539.         sb=sb*64+mdest*8+arb
  540.         if opcode='ADDI' then code=x2d('0600')+sb
  541.         else if opcode='SUBI' then code=x2d('0400')+sb
  542.         else if opcode='ANDI' then code=x2d('0200')+sb
  543.         else if opcode='ORI' then code=x2d('0000')+sb
  544.         else if opcode='CMPI' then code=x2d('0c00')+sb
  545.         else if opcode='EORI' then code=x2d('0a00')+sb
  546.         else if opcode='SUBQ' then code=x2d('5100')+sb+imm*512
  547.         else code=x2d('5000')+sb+imm*512
  548.  
  549.         call PushWord code
  550.  
  551.         if substr(opcode,4,1)~='Q' then
  552.             do
  553.                 if size='B' then call PushWord imm
  554.                 else if (size='W') | (size='') then call PushWord imm
  555.                 else call PushLong imm
  556.             end
  557.  
  558.         extwrd=extra
  559.         if GetArg(mdest'|'dest'|'size)=-1 then return 0
  560.     end
  561. else if opcode='CMP' then
  562.     do
  563.         call SplitArgs arg
  564.  
  565.         if substr(dest,1,1)='D' then
  566.             do
  567.                 sb=SizeBits(size)
  568.                 if sb=-1 then return 0
  569.                 rb=RegBits(dest)
  570.                 if rb=-1 then return 0
  571.                 code=x2d('b000')+rb*512+sb*64
  572.             end
  573.         else
  574.             do
  575.                 'print "Destination must be a data register !\0a"'
  576.                 return 0
  577.             end
  578.         msource=ModeBits(source)
  579.         if msource=-1 then return 0
  580.         arb=ArgRegBits(msource'|'source)
  581.         if arb=-1 then return 0
  582.         code=code+msource*8+arb
  583.         call PushWord code
  584.         extwrd=extra
  585.         if GetArg(msource'|'source'|'size)=-1 then return 0
  586.     end
  587. else if opcode='CMPA' then
  588.     do
  589.         call SplitArgs arg
  590.  
  591.         if substr(dest,1,1)='A' then
  592.             do
  593.                 asb=AddressSizeBits(size)
  594.                 if asb=-1 then return 0
  595.                 rb=RegBits(dest)
  596.                 if rb=-1 then return 0
  597.                 code=x2d('b000')+rb*512+asb*64
  598.             end
  599.         else
  600.             do
  601.                 'print "Destination must be an address register !\0a"'
  602.                 return 0
  603.             end
  604.         msource=ModeBits(source)
  605.         if msource=-1 then return 0
  606.         arb=ArgRegBits(msource'|'source)
  607.         if arb=-1 then return 0
  608.         code=code+msource*8+arb
  609.         call PushWord code
  610.         extwrd=extra
  611.         if GetArg(msource'|'source'|'size)=-1 then return 0
  612.     end
  613. else if opcode='CMPM' then
  614.     do
  615.         call SplitArgs arg
  616.  
  617.         parse var source '(A' sreg ')+'
  618.         parse var dest '(A' dreg ')+'
  619.         sreg='A'sreg
  620.         dreg='A'dreg
  621.  
  622.         sb=SizeBits(size)
  623.         if sb=-1 then return 0
  624.         rb=RegBits(sreg)
  625.         if rb=-1 then return 0
  626.         rbd=RegBits(dreg)
  627.         if rbd=-1 then return 0
  628.         code=x2d('b108')+sb*64+rb*512+rbd
  629.         call PushWord code
  630.     end
  631. else if ((substr(opcode,1,2)='DB') & (length(opcode)=4)) | (opcode='DBT') | (opcode='DBF') then
  632.     do
  633.         if opcode='DBT' then code=x2d('50c8')
  634.         else if (opcode='DBF') | (opcode='DBRA') then code=x2d('51c8')
  635.         else
  636.             do
  637.                 p=pos(substr(opcode,3,2),'HI LS CC CS NE EQ VC VS PL MI GE LT GT LE')
  638.                 if p=0 then
  639.                     do
  640.                         'print "Unknown opcode !\0a"'
  641.                         return 0
  642.                     end
  643.                 else code=x2d('50c8')+((p-1)/3+2)*256
  644.             end
  645.  
  646.         call SplitArgs arg
  647.         if substr(source,1,1)~='D' then
  648.             do
  649.                 'print "Count register must be a data register !\0a"'
  650.                 return 0
  651.             end
  652.         rb=RegBits(source)
  653.         if rb=-1 then return 0
  654.         code=code+rb
  655.         call PushWord code
  656.         'void' dest
  657.         if rc~=0 then
  658.             do
  659.                 'print "Bad integer !\0a"'
  660.                 return 0
  661.             end
  662.         dest=result
  663.         dest=dest-pc-2
  664.         call PushWord dest
  665.     end
  666. else if opcode='EOR' then
  667.     do
  668.         call SplitArgs arg
  669.  
  670.         if substr(source,1,1)='D' then
  671.             do
  672.                 sb=SizeBits(size)
  673.                 if sb=-1 then return 0
  674.                 rb=RegBits(source)
  675.                 if rb=-1 then return 0
  676.                 code=x2d('b100')+rb*512+sb*64
  677.             end
  678.         else
  679.             do
  680.                 'print "Source must be a data register !\0a"'
  681.                 return 0
  682.             end
  683.         mdest=ModeBits(dest)
  684.         if mdest=-1 then return 0
  685.         arb=ArgRegBits(mdest'|'dest)
  686.         if arb=-1 then return 0
  687.         code=code+mdest*8+arb
  688.         call PushWord code
  689.         extwrd=extra
  690.         if GetArg(mdest'|'dest'|'size)=-1 then return 0
  691.     end
  692. else if opcode='ILLEGAL' then call PushWord x2d('4afc')
  693. else if opcode='RESET' then call PushWord x2d('4e70')
  694. else if (opcode='JMP') | (opcode='JSR') then
  695.     do
  696.         if opcode='JMP' then code=x2d('4ec0')
  697.         else code=x2d('4e80')
  698.         marg=ModeBits(arg)
  699.         if marg=-1 then return 0
  700.         arb=ArgRegBits(marg'|'arg)
  701.         if arb=-1 then return 0
  702.         code=code+marg*8+arb
  703.         call PushWord code
  704.         extwrd=extra
  705.         if GetArg(marg'|'arg'|W')=-1 then return 0
  706.     end
  707. else if opcode='LEA' then
  708.     do
  709.         call SplitArgs arg
  710.  
  711.         if substr(dest,1,1)='A' then
  712.             do
  713.                 rb=RegBits(dest)
  714.                 if rb=-1 then return 0
  715.                 code=x2d('41c0')+rb*512
  716.             end
  717.         else
  718.             do
  719.                 'print "Destination must be an address register !\0a"'
  720.                 return 0
  721.             end
  722.         msource=ModeBits(source)
  723.         if msource=-1 then return 0
  724.         arb=ArgRegBits(msource'|'source)
  725.         if arb=-1 then return 0
  726.         code=code+msource*8+arb
  727.         call PushWord code
  728.         extwrd=extra
  729.         if GetArg(msource'|'source'|L')=-1 then return 0
  730.     end
  731. else if opcode='MOVEM' then
  732.     do
  733.         call SplitArgs arg
  734.  
  735.         if (pos('-',source)~=0) | (pos('/',source)~=0) | ((length(source)=2) & (pos(substr(source,1,1),'DA')~=0)) then
  736.             do
  737.                 list=source
  738.                 arg=dest
  739.                 code=x2d('4880')
  740.             end
  741.         else
  742.             do
  743.                 list=dest
  744.                 arg=source
  745.                 code=x2d('4c80')
  746.             end
  747.  
  748.         bits=RegListBits(list)
  749.         if bits=-1 then return 0
  750.         if substr(arg,1,2)~='-(' then bits=reverse(bits)
  751.         rlbits=c2d(b2c(bits))
  752.  
  753.         asb=AddressSizeBits(size)
  754.         if asb=-1 then return 0
  755.         code=code+(asb%4)*64
  756.  
  757.         marg=ModeBits(arg)
  758.         if marg=-1 then return 0
  759.         arb=ArgRegBits(marg'|'arg)
  760.         if arb=-1 then return 0
  761.         code=code+marg*8+arb
  762.         call PushWord code
  763.         call PushWord rlbits
  764.         extwrd=extra
  765.         if GetArg(marg'|'arg'|'size)=-1 then return 0
  766.     end
  767. else if opcode='MOVEQ' then
  768.     do
  769.         call SplitArgs arg
  770.         if substr(source,1,1)~='#' then
  771.             do
  772.                 'print "Bad immediate value !\0a"'
  773.                 return 0
  774.             end
  775.         if substr(dest,1,1)~='D' then
  776.             do
  777.                 'print "Destination must be a data register !\0a"'
  778.                 return 0
  779.             end
  780.  
  781.         parse var source '#' imm
  782.         'void' imm
  783.         if rc~=0 then
  784.             do
  785.                 'print "Bad integer !\0a"'
  786.                 return 0
  787.             end
  788.         imm=result
  789.  
  790.         rb=RegBits(dest)
  791.         if rb=-1 then return 0
  792.         code=x2d('7000')+rb*512+MakeByte(imm)
  793.         call PushWord code
  794.     end
  795. else if opcode='PEA' then
  796.     do
  797.         msource=ModeBits(arg)
  798.         if msource=-1 then return 0
  799.         code=x2d('4840')
  800.         arb=ArgRegBits(msource'|'arg)
  801.         if arb=-1 then return 0
  802.         code=code+msource*8+arb
  803.         call PushWord code
  804.         extwrd=extra
  805.         if GetArg(msource'|'arg'|L')=-1 then return 0
  806.     end
  807. else if opcode='SWAP' then
  808.     do
  809.         if substr(arg,1,1)~='D' then
  810.             do
  811.                 'print "Argument must be a data register !\0a"'
  812.                 return 0
  813.             end
  814.         rb=RegBits(arg)
  815.         if rb=-1 then return 0
  816.         code=x2d('4840')+rb
  817.         call PushWord code
  818.     end
  819. else if opcode='DC' then
  820.     do
  821.         'void' arg
  822.         if rc~=0 then
  823.             do
  824.                 'print "Bad integer !\0a"'
  825.                 return 0
  826.             end
  827.         arg=result
  828.         if size='B' then
  829.             do
  830.                 'print "Sorry DC.B not supported !\0a"'
  831.                 return 0
  832.             end
  833.         if (size='W') | (size='') then call PushWord arg
  834.         else if size='L' then call PushLong arg
  835.         else
  836.             do
  837.                 'print "Bad size specifier !\0a"'
  838.                 return 0
  839.             end
  840.     end
  841. else
  842.     do
  843.         'print "Unknown opcode !\0a"'
  844.         return 0
  845.     end
  846.  
  847. 'assign _m='pc
  848. do j=0 to extra-1
  849.     'assign *(_m+'j'*2).w='c.j
  850. end
  851. pc=pc+extra*2
  852. return 1
  853.  
  854.  
  855. /*-------------------------------*/
  856. /* Convert size specifier for     */
  857. /* MOVE to bits                        */
  858. /*                                            */
  859. /* Input   : size .B, .W, .L        */
  860. /* Uses    :                             */
  861. /* Changes :                             */
  862. /* Returns : -1 if error or bits    */
  863. /*-------------------------------*/
  864.  
  865. MoveSizeBits: procedure
  866. parse arg size
  867.  
  868.     if size='B' then return 1
  869.     else if (size='W') | (size='') then return 3
  870.     else if size='L' then return 2
  871.     else
  872.         do
  873.             'print "Bad size specifier !\0a"'
  874.             return -1
  875.         end
  876.  
  877.  
  878. /*-------------------------------*/
  879. /* Convert size specifier for     */
  880. /* address registers to bits        */
  881. /*                                            */
  882. /* Input   : size .W, .L            */
  883. /* Uses    :                             */
  884. /* Changes :                             */
  885. /* Returns : -1 if error or bits    */
  886. /*-------------------------------*/
  887.  
  888. AddressSizeBits: procedure
  889. parse arg size
  890.  
  891.     if (size='W') | (size='') then return 3
  892.     else if size='L' then return 7
  893.     else
  894.         do
  895.             'print "Bad size specifier !\0a"'
  896.             return -1
  897.         end
  898.  
  899.  
  900. /*-------------------------------*/
  901. /* Convert size specifier            */
  902. /* to bits                                */
  903. /*                                            */
  904. /* Input   : size .B, .W, .L        */
  905. /* Uses    :                             */
  906. /* Changes :                             */
  907. /* Returns : -1 if error or bits    */
  908. /*-------------------------------*/
  909.  
  910. SizeBits: procedure
  911. parse arg size
  912.  
  913.     if size='B' then return 0
  914.     else if (size='W') | (size='') then return 1
  915.     else if size='L' then return 2
  916.     else
  917.         do
  918.             'print "Bad size specifier !\0a"'
  919.             return -1
  920.         end
  921.  
  922.  
  923. /*-------------------------------*/
  924. /* Convert register to bits        */
  925. /*                                            */
  926. /* Input   : reg A0..A7 D0..D7    */
  927. /* Uses    :                             */
  928. /* Changes :                             */
  929. /* Returns : -1 if error or bits    */
  930. /*-------------------------------*/
  931.  
  932. RegBits: procedure
  933. parse arg reg
  934.  
  935.     l=substr(reg,1,1)
  936.     if ((l='D') | (l='A')) & (length(reg)=2) then return substr(reg,2,1)
  937.     else
  938.         do
  939.             'print "Bad register name !\0a"'
  940.             return -1
  941.         end
  942.  
  943.  
  944. /*-------------------------------*/
  945. /* Convert parameter to bits        */
  946. /* corresponding with mode field    */
  947. /* in most instructions                */
  948. /*                                            */
  949. /* Input   : addressing arg        */
  950. /* Uses    :                             */
  951. /* Changes :                             */
  952. /* Returns : -1 if error or bits    */
  953. /*-------------------------------*/
  954.  
  955. ModeBits: procedure
  956. parse arg argum
  957.  
  958.     l=substr(argum,1,1)
  959.     if l='(' then
  960.         do
  961.             if pos('PC',argum) ~= 0 then return 7
  962.             l=substr(argum,2,1)
  963.             if l='A' then
  964.                 do
  965.                     if substr(argum,5,1)='+' then return 3
  966.                     else return 2
  967.                 end
  968.             else
  969.                 do
  970.                     if pos(',',argum)=0 then return 7
  971.                     parse var argum left ',' right
  972.                     if pos(',',right)=0 then return 5
  973.                     else return 6
  974.                 end
  975.         end
  976.     else if l='A' then return 1
  977.     else if l='D' then return 0
  978.     else if l='-' then return 4
  979.     else if l='#' then return 7
  980.     else
  981.         do
  982.             'print "Bad argument format !\0a"'
  983.             return -1
  984.         end
  985.  
  986.  
  987. /*-------------------------------------*/
  988. /* Convert parameter to bits                */
  989. /* corresponding with register            */
  990. /* field in most instructions                */
  991. /* ('mode' in Input is the value            */
  992. /* returned by 'ModeBits')                    */
  993. /*                                                    */
  994. /* Input   : mode '|' addressing arg    */
  995. /* Uses    :                                     */
  996. /* Changes :                                     */
  997. /* Returns : -1 if error or bits            */
  998. /*-------------------------------------*/
  999.  
  1000. ArgRegBits: procedure
  1001. parse arg mode '|' argum
  1002.  
  1003.     if (mode=0) | (mode=1) then return RegBits(argum)
  1004.     else if (mode=2) | (mode=3) | (mode=4) then
  1005.         do
  1006.             parse var argum '(A' reg
  1007.             reg=substr(reg,1,1)
  1008.             return RegBits('A'reg)
  1009.         end
  1010.     else if mode~=7 then    /* 5 and 6 */
  1011.         do
  1012.             parse var argum ',A' reg
  1013.             reg=substr(reg,1,1)
  1014.             return RegBits('A'reg)
  1015.         end
  1016.     else
  1017.         do
  1018.             l=substr(argum,1,1)
  1019.             if l='#' then return 4
  1020.             else
  1021.                 do
  1022.                     parse var argum '(' xxx ')' yyy
  1023.                     if yyy='.W' then return 0
  1024.                     else if yyy='.L' then return 1
  1025.  
  1026.                     parse var argum '(' xxx ',' yyy
  1027.                     if yyy='PC)' then return 2
  1028.                     else if index(argum,'PC') ~= 0 then return 3
  1029.                     else return 1
  1030.                 end
  1031.         end
  1032.  
  1033.  
  1034. /*-------------------------*/
  1035. /* Push a word to memory    */
  1036. /*                                    */
  1037. /* Input   : word to push    */
  1038. /* Uses    : c. extra        */
  1039. /* Changes : c. extra        */
  1040. /* Returns :                    */
  1041. /*-------------------------*/
  1042.  
  1043. PushWord: procedure expose c. extra
  1044. parse arg word
  1045.  
  1046.     c.extra=MakeWord(word)
  1047.     extra=extra+1
  1048.     return
  1049.  
  1050.  
  1051. /*-------------------------*/
  1052. /* Push a long to memory    */
  1053. /*                                    */
  1054. /* Input   : long to push    */
  1055. /* Uses    : c. extra        */
  1056. /* Changes : c. extra        */
  1057. /* Returns :                    */
  1058. /*-------------------------*/
  1059.  
  1060. PushLong: procedure expose c. extra
  1061. parse arg long
  1062.  
  1063.     c.extra=MakeWord(x2d(left(d2x(long,8),4)))
  1064.     extra=extra+1
  1065.     c.extra=MakeWord(x2d(d2x(long,4)))
  1066.     extra=extra+1
  1067.     return
  1068.  
  1069.  
  1070. /*----------------------------------------------*/
  1071. /* Parse a normal addressing argument                */
  1072. /* and push words to memory                            */
  1073. /*                                                                */
  1074. /* Input   : mode '|' addressing arg '|' size    */
  1075. /* Uses    : c. extra pc extwrd                        */
  1076. /* Changes : c. extra                                    */
  1077. /* Returns : -1 if error or 0                            */
  1078. /*----------------------------------------------*/
  1079.  
  1080. GetArg: procedure expose c. extra pc extwrd
  1081. parse arg mode '|' argum '|' size
  1082.  
  1083.     if (mode=0) | (mode=1) | (mode=2) | (mode=3) | (mode=4) then
  1084.         return 0
  1085.     else if mode=5 then
  1086.         do
  1087.             parse var argum '(' xxx ','
  1088.             'void' xxx
  1089.             if rc~=0 then
  1090.                 do
  1091.                     'print "Bad integer !\0a"'
  1092.                     return -1
  1093.                 end
  1094.             xxx=result
  1095.             if (xxx<=32767) & (xxx>=-32768) then call PushWord xxx
  1096.             else if (xxx<=65535) & (xxx>=0) then call PushWord xxx
  1097.             else
  1098.                 do
  1099.                     'print "Sorry, longword Ax relative not supported !\0a"'
  1100.                     return -1
  1101.                 end
  1102.             return 0
  1103.         end
  1104.     else if mode=7 then
  1105.         do
  1106.             reg=ArgRegBits(mode'|'argum)
  1107.             if reg=-1 then return -1
  1108.             else if reg=0 then
  1109.                 do
  1110.                     parse var argum '(' xxx ')'
  1111.                     'void' xxx
  1112.                     if rc~=0 then
  1113.                         do
  1114.                             'print "Bad integer !\0a"'
  1115.                             return -1
  1116.                         end
  1117.                     call PushWord result
  1118.                     return 0
  1119.                 end
  1120.             else if reg=1 then
  1121.                 do
  1122.                     parse var argum '(' xxx ')'
  1123.                     'void' xxx
  1124.                     if rc~=0 then
  1125.                         do
  1126.                             'print "Bad integer !\0a"'
  1127.                             return -1
  1128.                         end
  1129.                     call PushLong result
  1130.                     return 0
  1131.                 end
  1132.             else if reg=4 then
  1133.                 do
  1134.                     s=MoveSizeBits(size)
  1135.                     if s=-1 then return -1
  1136.                     parse var argum '#' xxx
  1137.                     'void' xxx
  1138.                     if rc~=0 then
  1139.                         do
  1140.                             'print "Bad integer !\0a"'
  1141.                             return -1
  1142.                         end
  1143.                     xxx=result
  1144.                     if s=2 then call PushLong xxx
  1145.                     else call PushWord xxx
  1146.                     return 0
  1147.                 end
  1148.             else if reg=2 then
  1149.                 do
  1150.                     parse var argum '(' xxx ','
  1151.                     'void' xxx
  1152.                     if rc~=0 then
  1153.                         do
  1154.                             'print "Bad integer !\0a"'
  1155.                             return -1
  1156.                         end
  1157.                     xxx=result
  1158.                     xxx=xxx-pc+extwrd*2-4
  1159.  
  1160.                     if (xxx<=32767) & (xxx>=-32768) then call PushWord xxx
  1161.                     else
  1162.                         do
  1163.                             'print "Sorry, longword PC relative not supported !\0a"'
  1164.                             return -1
  1165.                         end
  1166.                     return 0
  1167.                 end
  1168.             else
  1169.                 do
  1170.                     if pos('PC',argum)=0 then
  1171.                         do
  1172.                             'print "Illegal base register !\0a"'
  1173.                             return -1
  1174.                         end
  1175.                     return ParseComplexArg(argum'|PC')
  1176.                 end
  1177.         end
  1178.     else
  1179.         do
  1180.             parse var argum ',A' reg
  1181.             return ParseComplexArg(argum'|A'substr(reg,1,1))
  1182.         end
  1183.     return 0
  1184.  
  1185.  
  1186. /*----------------------------------------------*/
  1187. /* Parse a complex addressing argument                */
  1188. /* and push words to memory                            */
  1189. /*                                                                */
  1190. /* Input   : addressing arg '|' base register    */
  1191. /* Uses    : c. extra pc extwrd                        */
  1192. /* Changes : c. extra                                    */
  1193. /* Returns : -1 if error or 0                            */
  1194. /*----------------------------------------------*/
  1195.  
  1196. ParseComplexArg: procedure expose c. extra pc extwrd
  1197. parse arg argum '|' basereg
  1198.  
  1199.     if substr(argum,2,1)='[' then
  1200.         do
  1201.             parse var argum '([' bd ',' (basereg) rest
  1202.  
  1203.             if substr(rest,1,1)=']' then
  1204.                 do
  1205.                     postidx=4
  1206.                     parse var rest '],' reg ',' od ')'
  1207.                 end
  1208.             else
  1209.                 do
  1210.                     postidx=0
  1211.                     parse var rest ',' reg '],' od ')'
  1212.                 end
  1213.             parse var reg reg '.' idxsize '*' multi
  1214.             'void' bd
  1215.             if rc~=0 then
  1216.                 do
  1217.                     'print "Bad integer !\0a"'
  1218.                     return -1
  1219.                 end
  1220.             bd=result
  1221.             if basereg='PC' then bd=bd-pc+extwrd*2-4
  1222.             'void' od
  1223.             if rc~=0 then
  1224.                 do
  1225.                     'print "Bad integer !\0a"'
  1226.                     return -1
  1227.                 end
  1228.             od=result
  1229.  
  1230.             if (idxsize='W') | (idxsize='') then idxsize=0
  1231.             else if idxsize='L' then idxsize=1
  1232.             else
  1233.                 do
  1234.                     'print "Bad index size specifier !\0a"'
  1235.                     return -1
  1236.                 end
  1237.  
  1238.             idxreg=regbits(reg)
  1239.             if idxreg=-1 then return -1
  1240.             if substr(reg,1,1)='A' then idxdata=1
  1241.             else idxdata=0
  1242.  
  1243.             if (multi='') | (multi='1') then multi=0
  1244.             else if multi='2' then multi=1
  1245.             else if multi='4' then multi=2
  1246.             else if multi='8' then multi=3
  1247.             else
  1248.                 do
  1249.                     'print "Bad index scale !\0a"'
  1250.                     return -1
  1251.                 end
  1252.  
  1253.             if (od>32767) | (od<-32768) then postidx=postidx+3
  1254.             else postidx=postidx+2
  1255.  
  1256.             if (bd>32767) | (bd<-32768) then baseidx=3
  1257.             else baseidx=2
  1258.  
  1259.             call PushWord idxdata*32768+idxreg*4096+idxsize*2048+multi*512+256+baseidx*16+postidx
  1260.  
  1261.             if (bd>32767) | (bd<-32768) then call PushLong bd
  1262.             else call PushWord bd
  1263.  
  1264.             if (od>32767) | (od<-32768) then call PushLong od
  1265.             else call PushWord od
  1266.  
  1267.             return 0
  1268.         end
  1269.     else
  1270.         do
  1271.             parse var argum '(' bd ',' (basereg) ',' reg ')'
  1272.  
  1273.             parse var reg reg '.' idxsize '*' multi
  1274.             'void' bd
  1275.             if rc~=0 then
  1276.                 do
  1277.                     'print "Bad integer !\0a"'
  1278.                     return -1
  1279.                 end
  1280.             bd=result
  1281.             if basereg='PC' then bd=bd-pc+extwrd*2-4
  1282.  
  1283.             if (idxsize='W') | (idxsize='') then idxsize=0
  1284.             else if idxsize='L' then idxsize=1
  1285.             else
  1286.                 do
  1287.                     'print "Bad index size specifier !\0a"'
  1288.                     return -1
  1289.                 end
  1290.  
  1291.             idxreg=regbits(reg)
  1292.             if idxreg=-1 then return -1
  1293.             if substr(reg,1,1)='A' then idxdata=1
  1294.             else idxdata=0
  1295.  
  1296.             if (multi='') | (multi='1') then multi=0
  1297.             else if multi='2' then multi=1
  1298.             else if multi='4' then multi=2
  1299.             else if multi='8' then multi=3
  1300.             else
  1301.                 do
  1302.                     'print "Bad index scale !\0a"'
  1303.                     return -1
  1304.                 end
  1305.  
  1306.             if (bd>127) | (bd<-128) then
  1307.                 do
  1308.                     last9=256+32
  1309.                     if (bd>32767) | (bd<-32768) then
  1310.                         do
  1311.                             last9=last9+16
  1312.                         end
  1313.                 end
  1314.             else last9=bd
  1315.  
  1316.             call PushWord idxdata*32768+idxreg*4096+idxsize*2048+multi*512+last9
  1317.  
  1318.             if (bd>127) | (bd<-128)then
  1319.                 do
  1320.                     if (bd>32767) | (bd<-32768) then call PushLong bd
  1321.                     else call PushWord bd
  1322.                 end
  1323.             return 0
  1324.         end
  1325.  
  1326.  
  1327. /*-------------------------------*/
  1328. /* Split argument in two parts    */
  1329. /* source and destination            */
  1330. /*                                            */
  1331. /* Input   : argument                */
  1332. /* Uses    :                            */
  1333. /* Changes : source dest            */
  1334. /* Returns :                            */
  1335. /*-------------------------------*/
  1336.  
  1337. SplitArgs: procedure expose source dest
  1338. parse arg arg
  1339.  
  1340.     parse var arg lsrc '(' source ')' rsrc ',' dest
  1341.     if source='' then
  1342.         do
  1343.             parse var arg source ',' dest
  1344.         end
  1345.     else if dest='' then
  1346.         do
  1347.             parse var arg source ',' dest
  1348.         end
  1349.     else source=lsrc'('source')'rsrc
  1350.     return
  1351.  
  1352.  
  1353. /*-------------------------------------*/
  1354. /* Convert register list to bit string    */
  1355. /*                                                    */
  1356. /* Input   : register list                    */
  1357. /* Uses    :                                    */
  1358. /* Changes :                                     */
  1359. /* Returns : bit string or -1 if error    */
  1360. /*-------------------------------------*/
  1361.  
  1362. RegListBits: procedure
  1363. parse arg list
  1364.  
  1365.     bits='0000000000000000'
  1366.     regs='D0D1D2D3D4D5D6D7A0A1A2A3A4A5A6A7'
  1367.     rest=list
  1368.     do until rest=''
  1369.         parse var rest one '/' rest
  1370.         parse var one left '-' right
  1371.         l=pos(left,regs)
  1372.         if l=0 then
  1373.             do
  1374.                 'print "Bad register !\0a"'
  1375.                 return -1
  1376.             end
  1377.         l=(l-1)/2+1
  1378.         if right='' then
  1379.             bits=overlay('1',bits,l,1)
  1380.         else
  1381.             do
  1382.                 r=pos(right,regs)
  1383.                 if r=0 then
  1384.                     do
  1385.                         'print "Bad register !\0a"'
  1386.                         return -1
  1387.                     end
  1388.                 r=(r-1)/2+1
  1389.                 if ((l<=8) & (r>8)) | ((l>8) & (r<=8)) then
  1390.                     do
  1391.                         'print "Bad register pair !\0a"'
  1392.                         return -1
  1393.                     end
  1394.                 do i=l to r
  1395.                     bits=overlay('1',bits,i,1)
  1396.                 end
  1397.             end
  1398.     end
  1399.     return bits
  1400.  
  1401.  
  1402. /*----------------------------*/
  1403. /* Convert integer to a byte    */
  1404. /*                                        */
  1405. /* Input   : integer                */
  1406. /* Uses    :                        */
  1407. /* Changes :                         */
  1408. /* Returns : byte                    */
  1409. /*----------------------------*/
  1410.  
  1411. MakeByte: procedure
  1412. parse arg int
  1413.  
  1414.     'void' int'&255'
  1415.     return result
  1416.  
  1417.  
  1418. /*----------------------------*/
  1419. /* Convert integer to a word    */
  1420. /*                                        */
  1421. /* Input   : integer                */
  1422. /* Uses    :                        */
  1423. /* Changes :                         */
  1424. /* Returns : word                    */
  1425. /*----------------------------*/
  1426.  
  1427. MakeWord: procedure
  1428. parse arg int
  1429.  
  1430.     'void' int'&65535'
  1431.     return result
  1432.  
  1433.  
  1434.